package com.zhijian.medical.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.zhijian.medical.dao.local.SangerSjpzqMapper;
import com.zhijian.medical.entity.dto.SangerSjpzqPcrDto;
import com.zhijian.medical.entity.dto.SangerSjpzqSjDto;
import com.zhijian.medical.entity.dto.SangerSjpzqTxDto;
import com.zhijian.medical.entity.po.ExperimentProcessSampleLog;
import com.zhijian.medical.entity.po.Sanger;
import com.zhijian.medical.entity.po.SangerSjpzq;
import com.zhijian.medical.entity.vo.request.ExperimentProcessSampleSearchVo;
import com.zhijian.medical.entity.vo.request.SangerSjpzqSaveOrUpdateVo;
import com.zhijian.medical.entity.vo.request.SangerSjpzqSearchVo;
import com.zhijian.medical.entity.vo.response.ExperimentProcessSampleVo;
import com.zhijian.medical.entity.vo.response.SangerSjpzqVo;
import com.zhijian.medical.enums.AllExperimentationStepStatusEnum;
import com.zhijian.medical.enums.ExperimentTypeEnum;
import com.zhijian.medical.enums.SangerStatusEnum;
import com.zhijian.medical.enums.StatusEnum;
import com.zhijian.medical.holder.CurrentUserHolder;
import com.zhijian.medical.service.ExperimentProcessSampleLogService;
import com.zhijian.medical.service.ExperimentProcessSampleService;
import com.zhijian.medical.service.SangerService;
import com.zhijian.medical.service.SangerSjpzqService;
import com.zhijian.medical.util.AssertUtil;
import com.zhijian.medical.util.JsonUtil;
import com.zhijian.medical.util.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 一代测序-试剂配制区业务处理层
 *
 * @author HCG
 * @version: 1.0
 * @date 2022-08-11 17:18:27
 */
@Slf4j
@Service
public class SangerSjpzqServiceImpl implements SangerSjpzqService {

    @Autowired
    private SangerSjpzqMapper mapper;

    @Autowired
    private SangerService sangerService;

    @Autowired
    private ExperimentProcessSampleService experimentProcessSampleService;

    @Autowired
    private ExperimentProcessSampleLogService experimentProcessSampleLogService;

    @Override
    public SangerSjpzq selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public SangerSjpzq selectBySangerId(Long sangerId) {
        return mapper.selectBySangerId(sangerId);
    }

    @Override
    public SangerSjpzqVo selectVoById(Long id) {
        return mapper.selectVoById(id);
    }

    @Override
    public SangerSjpzqVo selectVoBySangerId(Long sangerId) {
        SangerSjpzqVo sangerSjpzqVo = mapper.selectVoBySangerId(sangerId);
        if (Objects.isNull(sangerSjpzqVo)) {
            return null;
        }
        Sanger sanger = sangerService.selectById(sangerId);
        if (Objects.isNull(sanger)) {
            return null;
        }
        sangerSjpzqVo.setResult(sanger.getStatus() > SangerStatusEnum.SJPZQ.getCode().byteValue() ?
                AllExperimentationStepStatusEnum.END.getCode().byteValue() : AllExperimentationStepStatusEnum.UN_END.getCode().byteValue());
        sangerSjpzqVo.setResultStr(sanger.getStatus() > SangerStatusEnum.SJPZQ.getCode().byteValue() ?
                AllExperimentationStepStatusEnum.END.getDesc() : AllExperimentationStepStatusEnum.UN_END.getDesc());
        String pcrData = sangerSjpzqVo.getPcrData();
        if (StringUtils.isNotBlank(pcrData)) {
            sangerSjpzqVo.setPcrDataList(JsonUtil.toArray(pcrData, SangerSjpzqPcrDto.class));
        }
        String mg2txpgdgfrData = sangerSjpzqVo.getMg2txpgdgfrData();
        if (StringUtils.isNotBlank(mg2txpgdgfrData)) {
            sangerSjpzqVo.setMg2txpgdgfrDataList(JsonUtil.toArray(mg2txpgdgfrData, SangerSjpzqTxDto.class));
        }
        String qtxckitData = sangerSjpzqVo.getQtxckitData();
        if (StringUtils.isNotBlank(qtxckitData)) {
            sangerSjpzqVo.setQtxckitDataList(JsonUtil.toArray(qtxckitData, SangerSjpzqTxDto.class));
        }
        String sjhywphhxsflrqData = sangerSjpzqVo.getSjhywphhxsflrqData();
        if (StringUtils.isNotBlank(sjhywphhxsflrqData)) {
            sangerSjpzqVo.setSjhywphhxsflrqDataList(JsonUtil.toArray(sjhywphhxsflrqData, SangerSjpzqSjDto.class));
        }
        return sangerSjpzqVo;
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteByPrimaryKey(id);
    }

    @Override
    public Long insert(SangerSjpzq sangerSjpzq) {
        Date now = new Date();
        sangerSjpzq.setCreateTime(now);
        sangerSjpzq.setUpdateTime(now);
        sangerSjpzq.setJcrq(DateUtil.formatDate(new Date()));
        sangerSjpzq.setWeatherJhstqsylcjlb(StatusEnum.UN_NORMAL.getCode().byteValue());
        sangerSjpzq.setSystmqj(StatusEnum.UN_NORMAL.getCode().byteValue());
        sangerSjpzq.setAzfzzsop010pzpcrfyy(StatusEnum.UN_NORMAL.getCode().byteValue());
        sangerSjpzq.setSjhywphhxsflrq(StatusEnum.UN_NORMAL.getCode().byteValue());
        sangerSjpzq.setQtxckit(StatusEnum.UN_NORMAL.getCode().byteValue());
        sangerSjpzq.setMg2txpgdgfr(StatusEnum.UN_NORMAL.getCode().byteValue());
        sangerSjpzq.setLxj(StatusEnum.NORMAL.getCode().byteValue());
        sangerSjpzq.setZdq(StatusEnum.NORMAL.getCode().byteValue());
        sangerSjpzq.setCjt(StatusEnum.NORMAL.getCode().byteValue());
        sangerSjpzq.setQjjzwxzssygztm(StatusEnum.UN_NORMAL.getCode().byteValue());
        sangerSjpzq.setQjyyq(StatusEnum.UN_NORMAL.getCode().byteValue());
        sangerSjpzq.setQjlxj(StatusEnum.UN_NORMAL.getCode().byteValue());
        sangerSjpzq.setClsyfqw(StatusEnum.UN_NORMAL.getCode().byteValue());
        return mapper.insert(sangerSjpzq) > 0 ? sangerSjpzq.getId() : 0L;
    }

    @Override
    public boolean update(SangerSjpzq sangerSjpzq) {
        Date now = new Date();
        sangerSjpzq.setUpdateTime(now);
        return mapper.updateByPrimaryKey(sangerSjpzq) != 0;
    }

    @Transactional(rollbackFor = Exception.class, value = "localTransactionManager")
    @Override
    public boolean update(SangerSjpzqSaveOrUpdateVo sangerSjpzqSaveOrUpdateVo) {
        Long sangerId = sangerSjpzqSaveOrUpdateVo.getSangerId();
        Sanger sanger = sangerService.selectById(sangerId);
        AssertUtil.notNull(sanger, "此实验不存在或者已被删除");
        SangerSjpzq sangerSjpzq = this.selectBySangerId(sangerId);
        AssertUtil.notNull(sangerSjpzq, "此试剂配制区数据不存在或者已被删除");
        if (sanger.getStatus() < SangerStatusEnum.HSZBQ.getCode().byteValue()) {
            //将实验的状态修改
            sangerService.updateByPrimaryKeySelective(Sanger.builder()
                    .id(sangerId)
                    .status(SangerStatusEnum.HSZBQ.getCode().byteValue())
                    .build());
        }
        SangerSjpzq updateParam = new SangerSjpzq();
        BeanUtils.copyProperties(sangerSjpzqSaveOrUpdateVo, updateParam);
        List<SangerSjpzqPcrDto> pcrDataList = sangerSjpzqSaveOrUpdateVo.getPcrDataList();
        if (CollectionUtil.isNotEmpty(pcrDataList)) {
            updateParam.setPcrData(JsonUtil.toString(pcrDataList));
        }
        List<SangerSjpzqTxDto> mg2txpgdgfrDataList = sangerSjpzqSaveOrUpdateVo.getMg2txpgdgfrDataList();
        if (CollectionUtil.isNotEmpty(mg2txpgdgfrDataList)) {
            updateParam.setMg2txpgdgfrData(JsonUtil.toString(mg2txpgdgfrDataList));
        }
        List<SangerSjpzqTxDto> qtxckitDataList = sangerSjpzqSaveOrUpdateVo.getQtxckitDataList();
        if (CollectionUtil.isNotEmpty(qtxckitDataList)) {
            updateParam.setQtxckitData(JsonUtil.toString(qtxckitDataList));
        }
        List<SangerSjpzqSjDto> sjhywphhxsflrqDataList = sangerSjpzqSaveOrUpdateVo.getSjhywphhxsflrqDataList();
        if (CollectionUtil.isNotEmpty(sjhywphhxsflrqDataList)) {
            updateParam.setSjhywphhxsflrqData(JsonUtil.toString(sjhywphhxsflrqDataList));
        }
        List<ExperimentProcessSampleVo> experimentProcessSampleVos = experimentProcessSampleService.selectList(ExperimentProcessSampleSearchVo.builder()
                .mainType(ExperimentTypeEnum.SANGER.getCode().byteValue())
                .experimentProcessId(sangerId)
                .build());
        //保存样本日志
        experimentProcessSampleLogService.saveBatch(experimentProcessSampleVos.stream().map(e -> ExperimentProcessSampleLog.builder()
                .sampleId(e.getId())
                .fishId(sangerId)
                .mainType(ExperimentTypeEnum.SANGER.getCode().byteValue())
                .op(String.format("%s%s-%s", sanger.getName(), sanger.getProcessNumber(), SangerStatusEnum.SJPZQ.getDesc()))
                .opUser(CurrentUserHolder.getUser().getName())
                .build()).collect(Collectors.toList()));
        return this.update(updateParam);
    }

    @Override
    public Integer count(SangerSjpzqSearchVo sangerSjpzqSearchVo) {
        return mapper.count(sangerSjpzqSearchVo);
    }

    @Override
    public List<SangerSjpzqVo> selectList(SangerSjpzqSearchVo sangerSjpzqSearchVo) {
        return mapper.selectList(sangerSjpzqSearchVo);
    }

    @Override
    public Page<SangerSjpzqVo> selectPage(SangerSjpzqSearchVo sangerSjpzqSearchVo) {
        //先直接查总数
        int count = count(sangerSjpzqSearchVo);
        //分页
        Page<SangerSjpzqVo> page = new Page<>(true, count, sangerSjpzqSearchVo.getPageNum(), sangerSjpzqSearchVo.getPageSize());
        sangerSjpzqSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<SangerSjpzqVo> responseVos = this.selectList(sangerSjpzqSearchVo);
        page.setData(responseVos);
        return page;
    }

}